package com.vegetable.modules.service.stock.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vegetable.common.annotation.CostAllocationOperation;
import com.vegetable.common.utils.R;
import com.vegetable.modules.entity.stock.CostAllocationRecord;
import com.vegetable.modules.entity.stock.CostWeightChangeSource;
import com.vegetable.modules.entity.stock.Stock;
import com.vegetable.modules.entity.stock.dto.CostAllocationDTO;
import com.vegetable.modules.mapper.stock.StockMapper;
import com.vegetable.modules.service.stock.ICostAllocationRecordService;
import com.vegetable.modules.service.stock.ICostAllocationService;
import com.vegetable.modules.service.stock.ICostWeightChangeSourceService;
import com.vegetable.modules.service.stock.IStockService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 库存成本分摊服务实现类
 * </p>
 *
 * @author Qwen
 * @since 2025-10-17
 */
@Slf4j
@Service
public class CostAllocationServiceImpl extends ServiceImpl<StockMapper, Stock> implements ICostAllocationService {
    
    @Resource
    private ICostWeightChangeSourceService costWeightChangeSourceService;
    
    @Resource
    private IStockService stockService;
    
    @Resource
    private ICostAllocationRecordService costAllocationRecordService;
    
    /**
     * 查询非零库存列表（关联商品分类信息）
     * @param page 分页对象
     * @param params 查询参数
     * @return 库存列表
     */
    @Override
    public IPage<Stock> getNonZeroStockWithCategory(IPage<Stock> page, Map<String, Object> params) {
        return stockService.getNonZeroStockWithCategory(page, params);
    }
    
    /**
     * 按重量分摊成本到选中的库存
     * 遵循库存成本分摊核心原则：当发生额外管理费用时，必须保持原始库存批次的成本不变，
     * 通过为剩余库存创建新批次的方式承载新增成本，确保历史数据的完整性和可追溯性。
     * 
     * @param allocationDTO 成本分摊参数
     * @return 分摊结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @CostAllocationOperation("按重量分摊成本")
    public R<List<String>> allocateCostByWeight(CostAllocationDTO allocationDTO) {
        try {
            log.info("开始执行按重量分摊成本，参数: {}", allocationDTO);
            
            // 1. 获取选中的库存列表
            List<Stock> selectedStocks = getStockDetails(allocationDTO.getSelectedStockIds());
            if (CollectionUtil.isEmpty(selectedStocks)) {
                log.warn("未找到选中的库存记录");
                return R.fail("未找到选中的库存记录");
            }
            
            log.info("找到 {} 条库存记录用于分摊", selectedStocks.size());
            
            // 2. 计算总重量
            BigDecimal totalWeight = selectedStocks.stream()
                    .map(Stock::getWeight)
                    .filter(Objects::nonNull)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            
            log.info("选中库存的总重量: {}", totalWeight);
            
            if (NumberUtil.equals(totalWeight, BigDecimal.ZERO)) {
                log.warn("选中库存的总重量为0，无法进行成本分摊");
                return R.fail("选中库存的总重量为0，无法进行成本分摊");
            }
            
            // 3. 计算单位重量成本
            BigDecimal unitCost = allocationDTO.getTotalCost().divide(totalWeight, 6, RoundingMode.HALF_UP);
            log.info("计算单位重量成本: {} / {} = {}", allocationDTO.getTotalCost(), totalWeight, unitCost);
            
            // 4. 对每个库存进行成本分摊处理
            List<String> resultMessages = new ArrayList<>();
            List<CostAllocationRecord> allocationRecords = new ArrayList<>();
            
            for (Stock stock : selectedStocks) {
                log.info("处理库存: ID={}, 描述={}", stock.getId(), stock.getFullDescription());
                AllocationResult result = processStockCostAllocation(stock, unitCost, allocationDTO);
                resultMessages.add(result.getMessage());
                if (result.getRecord() != null) {
                    allocationRecords.add(result.getRecord());
                    log.info("为库存 {} 创建分摊记录成功", stock.getId());
                } else {
                    log.warn("为库存 {} 创建分摊记录失败: {}", stock.getId(), result.getMessage());
                }
            }
            
            // 5. 批量保存分摊记录
            log.info("准备保存 {} 条分摊记录", allocationRecords.size());
            if (CollectionUtil.isNotEmpty(allocationRecords)) {
                boolean saveResult = costAllocationRecordService.saveBatch(allocationRecords);
                if (!saveResult) {
                    log.error("保存分摊记录失败");
                    return R.fail("保存分摊记录失败");
                }
                log.info("成功保存 {} 条分摊记录", allocationRecords.size());
            } else {
                log.warn("没有需要保存的分摊记录");
            }
            
            // 6. 保存成本变化记录
            log.info("开始保存成本变化记录");
            saveCostWeightChangeSource(selectedStocks, allocationDTO);
            
            log.info("成本分摊执行完成");
            return R.success("成本分摊成功" + resultMessages);
        } catch (Exception e) {
            log.error("成本分摊失败", e);
            return R.fail("成本分摊失败: " + e.getMessage());
        }
    }
    
    /**
     * 处理单个库存的成本分摊结果封装类
     */
    private static class AllocationResult {
        private String message;
        private CostAllocationRecord record;
        
        public AllocationResult(String message, CostAllocationRecord record) {
            this.message = message;
            this.record = record;
        }
        
        public String getMessage() {
            return message;
        }
        
        public CostAllocationRecord getRecord() {
            return record;
        }
    }
    
    /**
     * 处理单个库存的成本分摊
     * @param stock 库存记录
     * @param unitCost 单位重量成本
     * @param allocationDTO 分摊参数
     * @return 处理结果
     */
    private AllocationResult processStockCostAllocation(Stock stock, BigDecimal unitCost, CostAllocationDTO allocationDTO) {
        log.info("处理库存分摊: ID={}, 当前数量={}, 初始数量={}, 是否相等={}", 
            stock.getId(), stock.getNumber(), stock.getInitNumber(), 
            stock.getNumber() != null && stock.getInitNumber() != null && stock.getNumber().equals(stock.getInitNumber()));
        
        // 判断库存现在的数量是否等于入库数量
        if (stock.getNumber() != null && stock.getInitNumber() != null && stock.getNumber().equals(stock.getInitNumber())) {
            // 直接修改库存成本costWeight，保持原始库存批次的历史数据完整性和可追溯性
            log.info("库存 {} 数量未变化，直接更新成本", stock.getId());
            return updateExistingStockCost(stock, unitCost, allocationDTO);
        } else {
            // 新增一条库存信息，通过为剩余库存创建新批次的方式承载新增成本
            // 确保原始库存批次的成本不变，保持历史数据的完整性和可追溯性
            log.info("库存 {} 数量已变化，创建新批次记录", stock.getId());
            return createNewStockRecord(stock, unitCost, allocationDTO);
        }
    }
    
    /**
     * 更新现有库存的成本
     * 遵循核心原则：保持原始库存批次的成本不变，直接更新成本字段
     * 
     * @param stock 库存记录
     * @param unitCost 单位重量成本
     * @param allocationDTO 分摊参数
     * @return 处理结果
     */
    private AllocationResult updateExistingStockCost(Stock stock, BigDecimal unitCost, CostAllocationDTO allocationDTO) {
        try {
            log.info("开始更新库存 {} 的成本", stock.getId());
            
            // 记录修改前的成本
            BigDecimal beforeCostWeight = stock.getCostWeight();
            log.info("库存 {} 修改前的成本: {}", stock.getId(), beforeCostWeight);
            
            // 计算新的成本单价（原成本 + 分摊成本）
            BigDecimal newCostWeight = NumberUtil.add(stock.getCostWeight(), unitCost);
            log.info("计算新成本单价: {} + {} = {}", stock.getCostWeight(), unitCost, newCostWeight);
            
            // 更新库存记录
            Stock updateStock = new Stock();
            updateStock.setId(stock.getId());
            updateStock.setCostWeight(newCostWeight);
            
            // 计算新的总成本
            BigDecimal newTotalCost = NumberUtil.mul(newCostWeight, stock.getWeight());
            updateStock.setCost(newTotalCost);
            log.info("计算新的总成本: {} * {} = {}", newCostWeight, stock.getWeight(), newTotalCost);
            
            // 更新其他相关字段以保持数据一致性
            updateStock.setGoodsUnitPrice(stock.getGoodsUnitPrice());
            updateStock.setPackageUnitPrice(stock.getPackageUnitPrice());
            updateStock.setWmsUnitPrice(stock.getWmsUnitPrice());
            
            // 使用stockService来确保能被成本变化切面监控到
            boolean result = stockService.updateById(updateStock);
            log.info("更新库存 {} 结果: {}", stock.getId(), result);
            
            // 创建分摊记录
            CostAllocationRecord record = new CostAllocationRecord();
            record.setOriginalStockId(stock.getId());
            record.setAllocatedStockId(stock.getId());
            record.setAllocationBatchNo(stock.getStockBatchNo());
            record.setTotalCost(allocationDTO.getTotalCost());
            record.setBeforeCostWeight(beforeCostWeight);
            record.setAfterCostWeight(newCostWeight);
            record.setWeight(stock.getWeight());
            record.setUnitCost(unitCost);
            record.setOperatorId(allocationDTO.getOperatorId());
            record.setOperatorName(allocationDTO.getOperatorName());
            record.setRemark(allocationDTO.getRemark());
            
            String message;
            if (result) {
                message = String.format("库存[%s]成本更新成功，原成本：%s，新成本：%s", 
                    stock.getFullDescription(), beforeCostWeight, newCostWeight);
                log.info(message);
            } else {
                message = String.format("库存[%s]成本更新失败", stock.getFullDescription());
                log.error(message);
            }
            
            return new AllocationResult(message, record);
        } catch (Exception e) {
            log.error("更新库存成本失败", e);
            String message = String.format("库存[%s]成本更新异常：%s", stock.getFullDescription(), e.getMessage());
            return new AllocationResult(message, null);
        }
    }
    
    /**
     * 创建新的库存记录
     * 遵循核心原则：通过为剩余库存创建新批次的方式承载新增成本，确保原始库存批次的成本不变
     * 
     * @param originalStock 原始库存记录
     * @param unitCost 单位重量成本
     * @param allocationDTO 分摊参数
     * @return 处理结果
     */
    private AllocationResult createNewStockRecord(Stock originalStock, BigDecimal unitCost, CostAllocationDTO allocationDTO) {
        try {
            // 创建新的库存记录
            Stock newStock = new Stock();
            
            // 复制原始库存的所有属性
            newStock.setCommodityId(originalStock.getCommodityId());
            newStock.setCommodityName(originalStock.getCommodityName());
            newStock.setCommonCode(originalStock.getCommonCode());
            newStock.setCommodityTypeId(originalStock.getCommodityTypeId());
            newStock.setCategory(originalStock.getCategory());
            newStock.setOrderTime(originalStock.getOrderTime());
            newStock.setSpecsId(originalStock.getSpecsId());
            newStock.setSpecsName(originalStock.getSpecsName());
            newStock.setTag(originalStock.getTag());
            newStock.setStandard(originalStock.getStandard());
            
            // 设置新的数量和重量（与原始库存相同）
            newStock.setNumber(originalStock.getNumber());
            newStock.setInitNumber(originalStock.getNumber());
            newStock.setWeight(originalStock.getWeight());
            newStock.setInitWeight(originalStock.getWeight());
            
            // 设置新的成本（分摊的成本）
            newStock.setCostWeight(unitCost);
            BigDecimal totalCost = NumberUtil.mul(unitCost, originalStock.getWeight());
            newStock.setCost(totalCost);
            
            // 复制其他属性
            newStock.setStorageType(originalStock.getStorageType());
            newStock.setStorageOrderNo(originalStock.getStorageOrderNo());
            newStock.setWarehouseId(originalStock.getWarehouseId());
            newStock.setWarehouseName(originalStock.getWarehouseName());
            newStock.setAgentName(originalStock.getAgentName());
            newStock.setPackageCost(originalStock.getPackageCost());
            newStock.setGoodsUnitPrice(originalStock.getGoodsUnitPrice());
            newStock.setPackageUnitPrice(originalStock.getPackageUnitPrice());
            newStock.setWmsUnitPrice(originalStock.getWmsUnitPrice());
            newStock.setOrderId(originalStock.getOrderId());
            newStock.setDetailId(originalStock.getDetailId());
            newStock.setCreateTime(new Date());
            newStock.setVersion(0);
            
            // 生成新的批次号（在原批次号基础上加+1,+2等标识）
            String newBatchNo = generateNewBatchNo(originalStock.getStockBatchNo());
            newStock.setStockBatchNo(newBatchNo);
            
            // 使用stockService来确保能被成本变化切面监控到
            boolean result = stockService.save(newStock);
            
            // 检查新库存记录是否保存成功
            if (!result) {
                String message = String.format("为库存[%s]创建新批次记录失败", originalStock.getFullDescription());
                log.error(message);
                return new AllocationResult(message, null);
            }
            
            // 创建分摊记录
            CostAllocationRecord record = new CostAllocationRecord();
            record.setOriginalStockId(originalStock.getId());
            record.setAllocatedStockId(newStock.getId()); // 确保始终设置allocatedStockId
            record.setAllocationBatchNo(newBatchNo);
            record.setTotalCost(allocationDTO.getTotalCost());
            record.setBeforeCostWeight(originalStock.getCostWeight());
            record.setAfterCostWeight(unitCost);
            record.setWeight(originalStock.getWeight());
            record.setUnitCost(unitCost);
            record.setOperatorId(allocationDTO.getOperatorId());
            record.setOperatorName(allocationDTO.getOperatorName());
            record.setRemark(allocationDTO.getRemark());
            
            String message;
            // 注意：新创建的库存批次是独立的，不会影响已有的销售订单走货信息
            // 销售订单走货信息仍然指向原始库存批次
            message = String.format("为库存[%s]创建新批次[%s]记录成功，分摊成本：%s", 
                originalStock.getFullDescription(), newBatchNo, unitCost);
            
            return new AllocationResult(message, record);
        } catch (Exception e) {
            log.error("创建新库存记录失败", e);
            String message = String.format("为库存[%s]创建新批次记录异常：%s", originalStock.getFullDescription(), e.getMessage());
            return new AllocationResult(message, null);
        }
    }
    
    /**
     * 生成新的批次号
     * 确保新批次号的唯一性，同时保持与原始批次号的关联性
     * 
     * @param originalBatchNo 原始批次号
     * @return 新的批次号
     */
    private String generateNewBatchNo(String originalBatchNo) {
        if (originalBatchNo == null || originalBatchNo.isEmpty()) {
            return "BATCH_" + System.currentTimeMillis();
        }
        
        // 查找是否已存在带+数字后缀的批次号
        int maxSuffix = 0;
        
        // 查询数据库中已存在的相关批次号（使用基础批次号查询）
        String baseBatchNo = originalBatchNo;
        int plusIndex = originalBatchNo.indexOf('+');
        if (plusIndex > 0) {
            baseBatchNo = originalBatchNo.substring(0, plusIndex);
        }
        
        // 使用StockService查找相关库存记录
        List<Stock> relatedStocks = stockService.findStocksByBaseBatchNo(baseBatchNo);
        
        if (CollectionUtil.isNotEmpty(relatedStocks)) {
            for (Stock stock : relatedStocks) {
                String batchNo = stock.getStockBatchNo();
                if (batchNo != null && batchNo.startsWith(baseBatchNo)) {
                    // 检查是否有+数字后缀
                    String suffix = batchNo.substring(baseBatchNo.length());
                    if (suffix.startsWith("+")) {
                        try {
                            int suffixNum = Integer.parseInt(suffix.substring(1));
                            if (suffixNum > maxSuffix) {
                                maxSuffix = suffixNum;
                            }
                        } catch (NumberFormatException e) {
                            // 忽略无法解析的后缀
                        }
                    }
                }
            }
        }
        
        // 生成新的后缀
        int newSuffix = maxSuffix + 1;
        return baseBatchNo + "+" + newSuffix;
    }
    
    /**
     * 保存成本变化记录
     * 记录成本分摊的详细信息，确保历史数据的完整性和可追溯性
     * 
     * @param stocks 库存列表
     * @param allocationDTO 分摊参数
     */
    private void saveCostWeightChangeSource(List<Stock> stocks, CostAllocationDTO allocationDTO) {
        try {
            log.info("开始保存成本变化记录，库存数量: {}", stocks.size());
            
            List<CostWeightChangeSource> changeSources = new ArrayList<>();
            
            for (Stock stock : stocks) {
                log.info("处理库存 {} 的成本变化记录", stock.getId());
                
                CostWeightChangeSource changeSource = new CostWeightChangeSource();
                changeSource.setStockId(stock.getId());
                changeSource.setCommodityId(stock.getCommodityId());
                changeSource.setCommodityName(stock.getCommodityName());
                changeSource.setSpecsId(stock.getSpecsId());
                changeSource.setSpecsName(stock.getSpecsName());
                changeSource.setStockBatchNo(stock.getStockBatchNo());
                
                // 设置成本变化信息
                BigDecimal beforeCostWeight = stock.getCostWeight();
                changeSource.setBeforeCostWeight(beforeCostWeight);
                log.info("库存 {} 分摊前成本: {}", stock.getId(), beforeCostWeight);
                
                // 对于直接更新的库存，设置新的成本
                // 对于新创建的库存，需要根据实际情况设置
                changeSource.setAfterCostWeight(stock.getCostWeight());
                log.info("库存 {} 分摊后成本: {}", stock.getId(), stock.getCostWeight());
                
                // 计算变化差值
                if (stock.getCostWeight() != null && beforeCostWeight != null) {
                    changeSource.setChangeAmount(stock.getCostWeight().subtract(beforeCostWeight));
                    log.info("库存 {} 成本变化差值: {}", stock.getId(), stock.getCostWeight().subtract(beforeCostWeight));
                } else {
                    changeSource.setChangeAmount(BigDecimal.ZERO);
                    log.warn("库存 {} 成本数据不完整，变化差值设为0", stock.getId());
                }
                
                changeSource.setSourceType(3); // 费用分摊
                changeSource.setSourceOrderId(null);
                changeSource.setSourceOrderNo("COST_ALLOCATION_" + System.currentTimeMillis());
                changeSource.setSourceOrderType(null);
                changeSource.setOperatorId(allocationDTO.getOperatorId());
                changeSource.setOperatorName(allocationDTO.getOperatorName());
                changeSource.setOperateTime(new Date());
                changeSource.setRemark("费用分摊：" + allocationDTO.getRemark());
                
                changeSources.add(changeSource);
            }
            
            log.info("准备保存 {} 条成本变化记录", changeSources.size());
            if (CollectionUtil.isNotEmpty(changeSources)) {
                boolean saveResult = costWeightChangeSourceService.saveBatch(changeSources);
                if (saveResult) {
                    log.info("成功保存 {} 条成本变化记录", changeSources.size());
                } else {
                    log.error("保存成本变化记录失败");
                }
            } else {
                log.warn("没有需要保存的成本变化记录");
            }
        } catch (Exception e) {
            log.error("保存成本变化记录失败", e);
        }
    }
    
    /**
     * 根据库存ID获取库存详情
     * @param stockIds 库存ID列表
     * @return 库存详情列表
     */
    @Override
    public List<Stock> getStockDetails(List<Long> stockIds) {
        log.info("获取库存详情，库存ID列表: {}", stockIds);
        
        if (CollectionUtil.isEmpty(stockIds)) {
            log.warn("库存ID列表为空");
            return new ArrayList<>();
        }
        
        QueryWrapper<Stock> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", stockIds);
        List<Stock> stocks = this.list(queryWrapper);
        
        log.info("查询到 {} 条库存记录", stocks.size());
        for (Stock stock : stocks) {
            log.info("库存详情 - ID: {}, 数量: {}, 初始数量: {}, 重量: {}, 成本单价: {}", 
                stock.getId(), stock.getNumber(), stock.getInitNumber(), stock.getWeight(), stock.getCostWeight());
        }
        
        return stocks;
    }
    
    /**
     * 根据库存ID获取相关的分摊记录
     * @param stockId 库存ID
     * @return 分摊记录列表
     */
    @Override
    public List<CostAllocationRecord> getAllocationRecordsByStockId(Long stockId) {
        log.info("查询库存 {} 的分摊记录", stockId);
        
        if (stockId == null) {
            log.warn("库存ID为空");
            return new ArrayList<>();
        }
        
        // 查询作为原始库存的分摊记录
        List<CostAllocationRecord> originalRecords = costAllocationRecordService.listByOriginalStockId(stockId);
        log.info("库存 {} 作为原始库存的分摊记录数量: {}", stockId, originalRecords != null ? originalRecords.size() : 0);
        if (originalRecords != null) {
            for (CostAllocationRecord record : originalRecords) {
                log.info("原始库存分摊记录 - ID: {}, 原始库存ID: {}, 分摊后库存ID: {}, 批次号: {}", 
                    record.getId(), record.getOriginalStockId(), record.getAllocatedStockId(), record.getAllocationBatchNo());
            }
        }
        
        // 查询作为分摊后库存的分摊记录
        List<CostAllocationRecord> allocatedRecords = costAllocationRecordService.listByAllocatedStockId(stockId);
        log.info("库存 {} 作为分摊后库存的分摊记录数量: {}", stockId, allocatedRecords != null ? allocatedRecords.size() : 0);
        if (allocatedRecords != null) {
            for (CostAllocationRecord record : allocatedRecords) {
                log.info("分摊后库存分摊记录 - ID: {}, 原始库存ID: {}, 分摊后库存ID: {}, 批次号: {}", 
                    record.getId(), record.getOriginalStockId(), record.getAllocatedStockId(), record.getAllocationBatchNo());
            }
        }
        
        // 合并结果
        List<CostAllocationRecord> allRecords = new ArrayList<>();
        if (originalRecords != null) {
            allRecords.addAll(originalRecords);
        }
        if (allocatedRecords != null) {
            allRecords.addAll(allocatedRecords);
        }
        
        // 按创建时间排序
        allRecords.sort((r1, r2) -> r2.getCreateTime().compareTo(r1.getCreateTime()));
        
        log.info("库存 {} 总共查询到 {} 条分摊记录", stockId, allRecords.size());
        return allRecords;
    }
    
    /**
     * 撤销按重量分摊成本
     * 遵循库存成本分摊核心原则：撤销分摊时需要恢复库存的原始状态，
     * 如果是创建新批次的分摊，则删除新创建的库存记录；
     * 如果是直接更新成本的分摊，则恢复原始成本单价
     * 
     * @param allocationRecordId 成本分摊记录ID
     * @return 撤销结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @CostAllocationOperation("撤销按重量分摊成本")
    public R<String> revokeCostAllocationByWeight(Long allocationRecordId) {
        try {
            // 1. 获取分摊记录
            CostAllocationRecord record = costAllocationRecordService.getById(allocationRecordId);
            if (record == null) {
                return R.fail("未找到指定的分摊记录");
            }
            
            // 2. 判断分摊类型（创建新批次 vs 直接更新）
            if (record.getAllocatedStockId() != null && !record.getAllocatedStockId().equals(record.getOriginalStockId())) {
                // 2.1 检查新创建的库存是否已经被走货
                Stock allocatedStock = stockService.getById(record.getAllocatedStockId());
                if (allocatedStock != null) {
                    // 检查是否已走货（数量或重量发生变化）
                    if (!Objects.equals(allocatedStock.getNumber(), allocatedStock.getInitNumber()) ||
                        !Objects.equals(allocatedStock.getWeight(), allocatedStock.getInitWeight())) {
                        return R.fail("分摊产生的新批次库存已被走货，无法撤销。请先将已出库的货物找回再进行撤销操作。");
                    }
                }
                
                // 2.2 创建新批次的分摊 - 删除新创建的库存记录
                boolean deleteResult = stockService.removeById(record.getAllocatedStockId());
                if (!deleteResult) {
                    return R.fail("删除新创建的库存记录失败");
                }
                
                log.info("撤销创建新批次的分摊记录，删除库存ID: {}", record.getAllocatedStockId());
            } else {
                // 2.3 直接更新成本的分摊 - 恢复原始成本单价
                Stock updateStock = new Stock();
                updateStock.setId(record.getOriginalStockId());
                updateStock.setCostWeight(record.getBeforeCostWeight());
                
                // 计算恢复后的总成本
                Stock originalStock = stockService.getById(record.getOriginalStockId());
                if (originalStock != null && originalStock.getWeight() != null) {
                    BigDecimal restoredTotalCost = record.getBeforeCostWeight().multiply(originalStock.getWeight());
                    updateStock.setCost(restoredTotalCost);
                }
                
                // 更新其他相关字段以保持数据一致性
                if (originalStock != null) {
                    updateStock.setGoodsUnitPrice(originalStock.getGoodsUnitPrice());
                    updateStock.setPackageUnitPrice(originalStock.getPackageUnitPrice());
                    updateStock.setWmsUnitPrice(originalStock.getWmsUnitPrice());
                }
                
                boolean updateResult = stockService.updateById(updateStock);
                if (!updateResult) {
                    return R.fail("恢复原始库存成本失败");
                }
                
                log.info("撤销直接更新成本的分摊记录，恢复库存ID: {} 的成本为: {}", 
                    record.getOriginalStockId(), record.getBeforeCostWeight());
            }
            
            // 3. 删除分摊记录
            boolean removeResult = costAllocationRecordService.removeById(allocationRecordId);
            if (!removeResult) {
                return R.fail("删除分摊记录失败");
            }
            
            // 4. 删除相关的成本变化记录
            QueryWrapper<CostWeightChangeSource> changeQueryWrapper = new QueryWrapper<>();
            changeQueryWrapper.eq("stock_id", record.getOriginalStockId());
            changeQueryWrapper.like("remark", "%费用分摊%");
            changeQueryWrapper.orderByDesc("operate_time"); // 按操作时间倒序，获取最新的记录
            changeQueryWrapper.last("LIMIT 1"); // 只获取最新的记录
            costWeightChangeSourceService.remove(changeQueryWrapper);
            
            return R.success("撤销成本分摊成功");
        } catch (Exception e) {
            log.error("撤销成本分摊失败", e);
            return R.fail("撤销成本分摊失败: " + e.getMessage());
        }
    }

}